package com.cyn.aframework.xml;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class XmlUtils {

    /**
     * map转xml map中没有根节点的键
     * @param map
     * @param rootName
     * @throws DocumentException
     * @throws IOException
     */
    public static Document map2xml(Map<String, Object> map, String rootName) throws DocumentException, IOException {
        Document doc = DocumentHelper.createDocument();
        Element root = DocumentHelper.createElement(rootName);
        doc.add(root);
        map2xml(map, root);
        //System.out.println(doc.asXML());
        //System.out.println(formatXml(doc));
        return doc;
    }

    /**
     * map转xml
     * @param map
     * @param body xml元素
     * @return
     */
    private static Element map2xml(Map<String, Object> map, Element body) {
        Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, Object> entry = entries.next();
            String key = entry.getKey();
            Object value = entry.getValue();
            if(key.startsWith("@")){	//属性
                body.addAttribute(key.substring(1, key.length()), value.toString());
            } else if(key.equals("#text")){	//有属性时的文本
                body.setText(value.toString());
            } else {
                if(value instanceof java.util.List ){
                    List list = (List)value;
                    Object obj;
                    for(int i=0; i<list.size(); i++){
                        obj = list.get(i);
                        //list里是map或String，不会存在list里直接是list的，
                        if(obj instanceof java.util.Map){
                            Element subElement = body.addElement(key);
                            map2xml((Map)list.get(i), subElement);

                        }else if(obj instanceof java.util.List){
                            Element subElement = body.addElement(key);
                            List list2 = (List)obj;
                            Object obj2;

                            for(int y=0; y<list2.size(); y++){
                                obj2 = list2.get(y);

                                if(obj2 instanceof java.util.Map){
                                    Element subElement2 = subElement.addElement(key+"_sub");
                                    map2xml((Map)list2.get(y), subElement2);
                                }else{

                                    body.addElement(key).setText((String)list2.get(y));
                                }

                            }


                        }else {
                            body.addElement(key).setText((String)list.get(i));
                        }
                    }
                } else if(value instanceof java.util.Map ){
                    Element subElement = body.addElement(key);
                    map2xml((Map)value, subElement);
                } else {
                    body.addElement(key).setText(value==null?"":value.toString());
                }
            }
            //System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
        }
        return body;
    }

    /**
     * 格式化输出xml
     * @param document
     * @return
     * @throws DocumentException
     * @throws IOException
     */
    public static String formatXml(Document document) throws DocumentException, IOException  {
        // 格式化输出格式
        //OutputFormat format = OutputFormat.createPrettyPrint();
        //createPrettyPrint传base64会多空格，暂时先用下面的代替。有问题再解决
        OutputFormat format = new OutputFormat(" ", true);
        //System.out.println(document);
        //format.setEncoding("UTF-8");
        StringWriter writer = new StringWriter();
        // 格式化输出流
        XMLWriter xmlWriter = new XMLWriter(writer, format);
        xmlWriter.setEscapeText(false);
        // 将document写入到输出流
        xmlWriter.write(document);
        xmlWriter.close();
        return writer.toString();
    }

    public static String formatXML(String inputXML) throws Exception {
        //inputXML = inputXML.replaceAll("\n", "").replaceAll("\r", "");
        SAXReader reader = new SAXReader();
        System.out.println("测试："+inputXML);
        Document document = reader.read(new StringReader(inputXML));
        String requestXML = null;
        XMLWriter writer = null;
        if (document != null) {
            try {
                StringWriter stringWriter = new StringWriter();
                OutputFormat format = new OutputFormat(" ", true);
                format.setNewLineAfterDeclaration(false);
                writer = new XMLWriter(stringWriter, format);
                writer.write(document);
                writer.flush();
                requestXML = stringWriter.getBuffer().toString();
            } finally {
                if (writer != null) {
                    try {
                        writer.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
        return requestXML;
    }

    public static void main(String[] args) throws IOException, DocumentException {
        Map<String,Object> items = new HashMap<>();
        items.put("a1","/system/ssquery/getFromDictData?cxfs=01&dictCode=DKLX&dictValue=01,02,03");
        items.put("a2","aqz2");

        String tmp = formatXml(map2xml(items,"test"));
        System.out.println(tmp);
    }
}
